﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using X23.EFCore.Repository;
using X23.Model;
using X23.Util.LinqUtil;

namespace X23.EFCore.Service
{
    public class CRUDService<TDto, T> : ICRUDService<TDto, T>
        where TDto : class
        where T : BaseAuditedEntity
    {
        /// <summary>
        /// 默认排序（按照id降序）
        /// </summary>
        private readonly List<AdvancedSort> defaultAdvancedSort = new() { new AdvancedSort { SortColumn = "Id" } };
        private readonly IMapper _mapper;
        private readonly IRepository<T> _repository;

        public CRUDService(IRepository<T> repository, IMapper mapper)
        {
            _mapper = mapper;
            _repository = repository;
        }
        public async virtual Task<List<TDto>> GetListAsync(Expression<Func<T, bool>> predicate, List<AdvancedSort> advancedSortList = null)
        {
            if (predicate == null)
            {
                predicate = x => true;
            }
            if (advancedSortList == null || advancedSortList.Count == 0)
            {
                advancedSortList = defaultAdvancedSort;
            }
            var result = (await _repository.GetAllAsync()).AdvancedSort(advancedSortList).ToList();
            return _mapper.Map<List<TDto>>(result);
        }


        public async virtual Task<PageData<TDto>> GetPageDataAsync(Expression<Func<T, bool>> predicate, int pages, int rows, List<AdvancedSort> advancedSortList = null)
        {
            if (predicate == null)
            {
                predicate = x => true;
            }
            if (advancedSortList == null || advancedSortList.Count == 0)
            {
                advancedSortList = defaultAdvancedSort;
            }
            var result = (await _repository.GetAllAsync()).Where(predicate).AdvancedSort(advancedSortList).ToPageList(pages, rows);
            return _mapper.Map<PageData<TDto>>(result);
        }

        public async virtual Task<TDto> AddAsync(TDto entity)
        {
            var data = _mapper.Map<T>(entity);
            if (await _repository.AddAsync(data))
            {
                return _mapper.Map<TDto>(data);
            }
            throw new Exception("添加错误");
        }

        public async virtual Task<TDto> UpdateAsync(TDto entity)
        {
            var data = _mapper.Map<T>(entity);

            if (await _repository.UpdateAsync(data))
            {
                return _mapper.Map<TDto>(data);
            }
            throw new Exception("修改错误");
        }

        public async virtual Task<bool> DeleteAsync(object id, bool isPhysicalDelete = false)
        {
            return await _repository.DeleteAsync(id, isPhysicalDelete);
        }

        public async virtual Task<TDto> GetByIdAsync(object id)
        {
            var data = await _repository.GetByIdAsync(id);
            return _mapper.Map<TDto>(data);
        }
    }
}
